package lk.icta.core.web.action;

import lk.icta.common.AppConstants;
import lk.icta.common.ELandRuntimeException;
import lk.icta.common.dao.DSDivisionDAO;
import lk.icta.common.dao.DistrictDAO;
import lk.icta.common.dao.GNDivisionDAO;
import lk.icta.common.entity.Child;
import lk.icta.common.entity.Contacts;
import lk.icta.common.entity.DSDivision;
import lk.icta.common.service.DocumentManagementService;
import lk.icta.common.service.MailSenderService;
import lk.icta.common.web.WebConstants;
import lk.icta.common.web.action.DocumentUploadAction;
import lk.icta.core.entity.*;
import lk.icta.core.service.*;
import lk.icta.user.entity.User;
import lk.icta.user.service.UserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class AlienationAction extends DocumentUploadAction {
    private static final Logger logger = LoggerFactory.getLogger(AlienationAction.class);
    private final LandApplicationManagementService landApplicationManagementService;
    //TODO: move AM realted code to alienation method service
    private final AlienationManagementService alienationManagementService;
    private final LandManagementService landManagementService;
    private final MailSenderService mailSenderService;
    private final LandAssociationManagementService landAssociationManagementService;
    private final ObjectionManagementService objectionManagementService;
    private final UserManager userManager;

    private final DistrictDAO districtDAO;
    private final DSDivisionDAO dsDivisionDAO;
    private final GNDivisionDAO gnDivisionDAO;

    private LandApplication landApplication;
    private Holder holder;
    private Contacts contacts;
    private Contacts contactPerson;
    private LandAssociation landAssociation;
    private Land land;
    private long applicationId;
    private long personId;
    private long contactId;
    private long initApplicationId;
    private int alienationMethod;
    private long landRefNumber;
    private int newAlienation;

    /*Permit-0  Land Grants=1 Short Term Lease =2 Long Term Lease =3
* Releasing To Department=4 Vesting Order=5  Ought Right Grant =6 */
    private int alienationType;
    private Map<Integer, String> dsDivisionsSelectedList;

    private Map<Integer, String> alienationMethodList;
    private Map<Integer, String> alienationMethodSet;
    private String[] alienationMethodSelectedList;
    private Map<Integer, String> amSelectedList;

    private Map<Integer, String> purposeList;
    private List<LandApplication> landApplicationList;
    private List<Child> children;
    private List<Alienation> alienationList;
    /*Edit Mode =1  non edit mode =0 */
    private int editMode;
    private boolean objectionDisabled;
    private int otherMode;
    private int searchValue;
    private int[] dsDivisionsSelected;
    private long[] landSelected;

    private Map<Integer, String> districtListAll;
    private Map<Integer, String> districtList;
    private Map<Integer, String> dsDivisionList;
    private Map<Integer, String> gnDivisionList;
    private Map<Integer, String> alienationTypeList;
    private double rental;
    private List<Land> landList = new ArrayList<Land>();
    private List<Land> landChildList = new ArrayList<Land>();
    private long landId;
    private long landReferenceNumber;

    private boolean isComplete = false;
    private boolean ignoreWarnings = false;

    private boolean initGrantPage;
    private String permitNo;

    private String districtName;
    private String dsDivisionName;

    private String associationComment;

    private int gnDivisionId;
    private String localAuthorityName;
    private String geologicalType;
    private Double hectare;
    private String alienationMethodName;
    private String searchText;
    private int dsDivisionId;
    private int districtId;
    private Date dueDate;
    private String ordsName;
    private int signOrNot;

    private String comment;
    private String objections;
    private String slcObjections;
    private List<CommunicationMethod> communicationMethodAsList;

    private int onlineApplicantDistrictId;
    private int onlineApplicantDsDivisionId;
    private String serchedAlienationHolderName;
    private String searchedAlienationHolderNIC;
    private String searchedAlienationSerialNumber;
    private String searchedAlienationLandSerialNumber;
    private String searchedAlienationNumber;
    private int searchedAlienationMethodId;

    public AlienationAction(DocumentManagementService documentManagementService,
                            LandApplicationManagementService landApplicationManagementService,
                            AlienationManagementService alienationManagementService,
                            LandManagementService landManagementService,
                            DistrictDAO districtDAO,
                            DSDivisionDAO dsDivisionDAO,
                            GNDivisionDAO gnDivisionDAO,
                            MailSenderService mailSenderService,
                            UserManager userManager,
                            LandAssociationManagementService landAssociationManagementService,
                            ObjectionManagementService objectionManagementService) {
        super(documentManagementService);
        this.landApplicationManagementService = landApplicationManagementService;
        this.alienationManagementService = alienationManagementService;
        this.landManagementService = landManagementService;
        this.districtDAO = districtDAO;
        this.dsDivisionDAO = dsDivisionDAO;
        this.gnDivisionDAO = gnDivisionDAO;
        this.mailSenderService = mailSenderService;
        this.userManager = userManager;
        this.landAssociationManagementService = landAssociationManagementService;
        this.objectionManagementService = objectionManagementService;
    }

    public String pageLoadApplicationSearch() {
        populateDistricts();
        return SUCCESS;
    }

    public String pageLoadAlienationSearch() {
        populateAlienationMethodNames();
        populateDistricts();
        return SUCCESS;
    }

    public String pageLoadBySlc() {
        logger.debug("pageLoadBySlc ");
        return SUCCESS;
    }

    //add edit initial app, add detailed app
    public String addLandApp() {
        logger.debug("Adding land app : ");

        try { //validate AM list

            // if the purpose has not been selected by the user.
            if (getLandApplication().getLandUsage() != null && getLandApplication().getLandUsage().getId() == -1) {
                getLandApplication().setLandUsage(null);
            }

            if (initApplicationId > 0) { //detailed app

                if (user != null) {
                    logger.debug("Adding detailed Land Application {} -----------1 ", user.getUsername());
                }
                return addDetailedLandApplication();
            } else {
                if (user != null) {
                    logger.debug("Adding Initial Land Application {} -----------1 ", user.getUsername());
                }
                return addInitialLandApplication();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
    }

    //add edit initial app, add detailed app
    public String addOnlineLandApp() {
        logger.debug("Adding land app : ");
        try { //validate AM list
            int userDSId = (Integer) session.get(AppConstants.SESSION_ONLINE_USER_DS);

            // if the purpose has not been selected by the user.
            if (getLandApplication().getLandUsage() != null && getLandApplication().getLandUsage().getId() == -1) {
                getLandApplication().setLandUsage(null);
            }

            logger.debug("dS Division id from session {}", userDSId);

            landApplication.setDsDivision(dsDivisionDAO.getDSDivisionByPK(userDSId));
            return addInitialLandApplication();

        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
    }

    private void populateNewAlienationBasicLists() {
        dsDivisionsSelectedList = new HashMap<Integer, String>();
        populateAlienationMethodSet(alienationType);
        amSelectedList = new HashMap<Integer, String>();
        AlienationMethod am = alienationManagementService.getAlienationMethodById(1, user);
        amSelectedList.put(am.getId(), am.getEnName());
        populateBasicLists();
    }

    //Add Edit initial land app
    private String addInitialLandApplication() {
        //add  initial land app
        logger.debug("\n\nLanguage {}", landApplication.getCommunicationLanguage());
        logger.debug("\n\nMethod {}", landApplication.getCommunicationMethod());

        try {
            if (newAlienation == 1) {
                if (alienationMethodSelectedList == null || alienationMethodSelectedList.length == 0) {
                    populateNewAlienationBasicLists();
                    addActionError("Please Select at least one Alenation Method");
                    return SUCCESS;
                }
            }
            if (alienationMethodSelectedList != null && alienationMethodSelectedList.length > 0) {
                //TODO: move business logic to serveice
                landApplication.setAlienationMethods(populateAlienationMethods());
            } else {
                //TODO: move business logic to serveice
                landApplication.setPreferredAlienationMethod(alienationManagementService.getAlienationMethodById(alienationType, user));
            }

            //TODO: move business logic to serveice
            landApplication.setDsDivisions(populateDSDivisions());

            if (children != null && children.size() > 0) {
                List<Child> newChildList = new ArrayList<Child>();
                for (Child c : children) {
                    if (c != null) {
                        newChildList.add(c);
                    }
                }
                holder.setChildren(newChildList);
            }
            holder.setContacts(contacts);

            //releasing to institutes
            if (holder.getHolderType() == 0) {
                holder.setContactPerson(contactPerson);
            }

            landApplication.setHolder(holder);

            if (landApplication.getHolder() != null) {
                landApplication.getHolder().setChildren(holder.getChildren());
            }

            if (editMode == 1) {
                landApplicationManagementService.updateInitialLandApplication(landApplication, user);
                addActionMessage(getText("msg_save_success_init_application_changes"));
                logger.debug("Update land application of land Application id : {}", landApplication.getId());

            } else if (editMode == 0) {
                if (landApplication.getPreferredAlienationMethod() != null) {
                    if (landApplication.getPreferredAlienationMethod().getId() == AppConstants.LAND_GRANT) {
                        landApplicationManagementService.addLandGrantInitialApplication(landApplication, permitNo, user);
                    } else {
                        landApplicationManagementService.addLandInitialApplication(landApplication, user);
                    }
                } else {
                    landApplicationManagementService.addLandInitialApplication(landApplication, user);
                }
                addActionMessage(getText("msg_save_success_init_application"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("Exception e : {}", e);
            return ERROR;
        }
        populateBasicLists();
        logger.debug("loading Success page");
        return SUCCESS;
    }

    //Add details of lands and associate lands to the application
    private String addDetailedLandApplication() {
        logger.debug("add detailed land app");
        try {
            //validate AM list
            if (newAlienation == 1) {
                if (alienationMethodSelectedList == null || alienationMethodSelectedList.length == 0) {
                    populateNewAlienationBasicLists();
                    addActionError("Please Select at least one Alenation Method");
                    return SUCCESS;
                }
            }

            if (alienationType > 0) {  //AM already selected in initial app   - for releasing to institutes
                logger.debug("ALIENATION METHOD {}", alienationType);
                landApplication.setPreferredAlienationMethod(new AlienationMethod(alienationType));
            }
            landApplication.setDsDivisions(populateDSDivisions());

            //delete documents
            deleteDocument();

            landApplication.setAlienationMethods(populateAlienationMethods());
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));

            if (children != null && children.size() > 0) {
                List<Child> newChildList = new ArrayList<Child>();
                for (Child c : children) {
                    if (c != null) {
                        newChildList.add(c);
                    }
                }
                holder.setChildren(newChildList);
            }

            holder.setContacts(contacts);

            if (holder.getHolderType() == 0) { //institutes
                holder.setContactPerson(contactPerson);
            }

            landApplication.setHolder(holder);

            if (landApplication.getHolder() != null) {
                landApplication.getHolder().setChildren(holder.getChildren());
            }

            logger.debug("Edit Mode {}", editMode);
            logger.debug("initial applicatio id - {} ", landApplication.getInitApplicationId());

            if (landApplication.getInitApplicationId() == 0) {
                logger.debug("add new detailed land application {} : ", user.getUsername());
                landApplicationManagementService.addLandDetailApplication(landApplication, landReferenceNumber, landSelected, user);
            } else {
                logger.debug("modify detailed land application {} : ", user.getUsername());
                WorkflowTask workflowTask = landApplication.getWorkflowItem().getWorkflowTask();
                if (workflowTask == WorkflowTask.DETAILED_FORM_DATA_ENTRY || workflowTask == WorkflowTask.DETAILED_FORM_REJECTED) {
                    logger.debug("modify detailed land application {} : ", user.getUsername());
                    landApplicationManagementService.editLandDetailApplication(landApplication, landReferenceNumber, landSelected, user);

                } else if (workflowTask == WorkflowTask.DETAILED_FORM_APPROVED || workflowTask == WorkflowTask.INTERVIEW_DATA_ENTRY) {
                    if (isComplete) {
                        logger.debug("complete interview on detailed land application {} : ", user.getUsername());
                        landApplicationManagementService.interviewCompleteLandDetailApplication(landApplication, landReferenceNumber, landSelected, user);
                    } else {
                        logger.debug("interview on detailed land application {} : ", user.getUsername());
                        landApplicationManagementService.interviewLandDetailApplication(landApplication, landReferenceNumber, landSelected, user);
                    }

                } else if (workflowTask == WorkflowTask.LAND_ALLOCATION_APPROVED || workflowTask == WorkflowTask.ACCEPTED_AND_COMPLETED
                        || workflowTask == WorkflowTask.REJECTED) {
                    logger.debug("complete detailed land application {} : ", user.getUsername());
                    //check want to edit or not
                    if (editMode == AppConstants.COMPLETE_EDIT_MODE) {
                        //edit Complete application
                        landApplicationManagementService.acceptAndCompleteAndEditApplication(landApplication, landReferenceNumber, comment, user);
                    } else {
                        //not edit
                        landApplicationManagementService.acceptAndCompleteApplication(landApplication, landReferenceNumber, comment, user);
                    }
                }
            }
            landApplicationList = landApplicationManagementService.getApprovedApplicationList(user);
            populateBasicLists();
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("Exception e : {}", e);
            return ERROR;
        }

        addActionMessage(getText("msg_save_success_detail_application"));
        return SUCCESS;
    }

    public String attachLandToApplication() {
        logger.debug("attach a land to Application {}");
        try {

            if (alienationType > 0) {  //AM already selected in initial app   - for releasing to institutes
                logger.debug("ALIENATION METHOD {}", alienationType);
            } else {
                addActionError("Please Select Alienation Method!");
                return ERROR;
            }

            if (!validateLand()) {
                return ERROR;
            }

            if (!validateAssociation()) {
                return ERROR;
            }

            if (!validateAlienation()) {
                return ERROR;
            }

            logger.debug("attach land on detailed land application {} : ", user.getUsername());
            landApplicationManagementService.attachLandToApplication(landApplication.getId(), landReferenceNumber, landSelected, alienationType, user);

        } catch (ELandRuntimeException e) {
            logger.debug("{}{}", e.getMessage(), user.getUsername());
            addActionError(e.getMessage());
            return ERROR;
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("Exception e : {}", e);
            return ERROR;
        }
        addActionMessage("Land Attached Successfully!");
        return SUCCESS;
    }

    private boolean validateLand() {

        if (landReferenceNumber > 0) { //validate Land
            land = landManagementService.getLandById(landReferenceNumber);
            if (land == null) {
                addActionError("Invalid Land Reference Number!");
                return false;
            } else {   //If valid lnad ref number given by the user, The AM should also be selected
                logger.debug("Land found {}", land.getId());

                if (land.getApprovalState() != Land.ApprovalState.APPROVED) {
                    addActionError("Invalid Land Reference Number!");
                    return false;
                }
                if (land.getAlienationState() == Land.AlienationState.ALIENATED) {
                    addActionError("Land Already Alienated!");
                    return false;
                }
            }
        } else {
            addActionError("Invalid Land Reference Number!");
            return false;
        }
        return true;
    }


    private boolean validateAlienation() {
        logger.debug("validateAlienation");

        List<Alienation> alienationListAll = null;

        if (landSelected != null && landSelected.length > 0) {
            //Using Land Lots
            logger.debug(" Using Land Lots");

            for (long l : landSelected) {
                logger.debug("Using Land Lots landSelected {}", l);

                return alienationCheckBySlimsNoAndLandLots(l, alienationListAll);
            }
        } else {
            return alienationCheckBySlimsNo(landReferenceNumber);
        }
        return true;
    }

    private boolean alienationCheckBySlimsNo(long refNo) {
        List<Alienation> alienationList = alienationManagementService.getAlienationByLand(refNo, user);
        if (alienationList != null && alienationList.size() > 0) {
            LandApplication landApplication1 = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);

            for (Alienation alienation : alienationList) {
                if (alienation.getStatus().equals(Alienation.State.PENDING)) {
                    if (landApplication1.getAlienationDetails() != null && landApplication1.getAlienationDetails().getLand().getId() == refNo) {  // Same land id as attached land id is given only for one land ignoring land list
                        logger.debug("The land is with same ref no: {}", refNo);
                        return true;
                    } else {
                        logger.debug("Alienation state is PENDING for land ref no: {} other {}", refNo, alienation.getHolder().getName());
                        addActionError("This Land Can't be attached !");
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private boolean alienationCheckBySlimsNoAndLandLots(long refNo, List<Alienation> alienationListAll) {
        List<Alienation> alienationList = alienationManagementService.getAlienationByLand(refNo, user);

        if (alienationList != null && alienationList.size() > 0) {
            for (Alienation alienation : alienationList) {
                if (alienation.getStatus().equals(Alienation.State.PENDING)) {

                    if (alienation.getLandList() != null && alienation.getLandList().size() > 0) {
                    } else {
                        addActionError("This Land Can't be attached !");
                        return false;
                    }
                } else {
                    addActionError("This Land Can't be attached !");
                    return false;
                }
            }
        } else {
            if (alienationListAll != null && alienationListAll.size() > 0) {
                //check parent land
                land = landManagementService.getLandById(refNo);
                long parentLandId = 0;

                for (Alienation alienationAll : alienationListAll) {
                    if (alienationAll != null) {
                        //check parent land
                        if (parentLandId == alienationAll.getLand().getId() && alienationAll.getLandList().size() == 0) {
                            addActionError("This Land Can't be attached , Parent Land already attached !");
                            return false;
                        } else {
                            List<Land> landList = alienationAll.getLandList();
                            if (landList != null && landList.size() > 0) {
                                for (Land l : landList) {
                                    if (l.getId() == refNo) {
                                        addActionError("This Land  Can't be attached !");
                                        return false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return true;
    }


    private boolean validateAssociation() {
        landAssociation = landAssociationManagementService.getAlienationMethodMetadataByLand(land.getId(), user);

        if (landAssociation == null) {
            addActionError("This Land Can't be attached , please Define Alienation method for Land before attached!");
            return false;
        }

        if (landAssociation.getDefineAMState() != LandAssociation.DefineAMState.APPROVED) {
            addActionError("This Land Can't be attached , please Define Alienation method for Land before attached!");
            return false;
        }

        if (landAssociation.getAlienationMethod().getId() != alienationType) {
            addActionError("This Land Can't be attached , Land Alienation method is different! " +
                    "This land can be alienated only under " + landAssociation.getAlienationMethod().getEnName());
            return false;
        }
        return true;
    }

    public String rejectAndCompleteApplication() {
        try {
            landApplicationManagementService.rejectAndCompleteApplication(landApplication, landReferenceNumber, comment, user);
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
        addActionMessage("Land Application rejected by the applicant");
        return SUCCESS;
    }

    public String acceptAndCompleteApplication() {
        try {
            landApplicationManagementService.acceptAndCompleteApplication(landApplication, landReferenceNumber, comment, user);
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
        addActionMessage("Land Application accept by the applicant");
        return SUCCESS;
    }

    public String handleObjections() {
        try {
            logger.debug("objection entry on detailed land application {} : ", user.getUsername());
            logger.debug("objection entry on detailed land application objections {} : ", objections);
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.handleObjections(landApplication, comment, objections, WorkflowTask.OBJECTION_DATA_ENTRY, user);
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
        addActionMessage("Objection details saved successfully!");
        return SUCCESS;
    }

    public String noObjections() {
        try {
            logger.debug("No objection on detailed land application {} : ", user.getUsername());
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.handleObjections(landApplication, comment, objections, WorkflowTask.OBJECTION_HANDLING_COMPLETED, user);
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
        addActionMessage("Application is marked as there are no objections for this application!");
        return SUCCESS;
    }


    public String completeObjectionHandling() {
        logger.debug("complete objection on detailed land application {} : ", user.getUsername());
        try {
            logger.debug("objection entry on detailed land application {} : ", user.getUsername());
            landApplicationManagementService.handleObjections(landApplication, comment, objections, WorkflowTask.OBJECTION_HANDLING_COMPLETED, user);

        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
        addActionMessage("Objection handling completed successfully!");
        return SUCCESS;
    }

    public String notSubmittedAndCompleteApplication() {
        try {
            landApplicationManagementService.notReceivedCompleteApplication(landApplication, landReferenceNumber, comment, user);
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }
        addActionMessage("Land Alienation rejected as it is not submitted by the applicant by due date");
        return SUCCESS;
    }

    public String approveLandAllocation() {
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.approveAttachedLand(landApplication, comment, user);
            addActionMessage("Land Allocation Approve success !");
            return SUCCESS;

        } catch (Exception e) {
            e.printStackTrace();
            addActionError("Land Allocation Approval failed!");
            return ERROR;
        }
    }

    public String rejectLandAllocation() {
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.rejectAttachedLand(landApplication, comment, user);
            addActionMessage("Land Allocation Reject success !");
            return SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            addActionError("Land Allocation Rejection failed!");
            return ERROR;
        }
    }

    public String saveAttachedAlienationDoc() {
        try {
            logger.debug("saveAttachedAlienationDoc : {}", getUploadedfileList(ModuleType.ATTACH_ALIENATION_DOC).size());
            if (getUploadedfileList(ModuleType.ATTACH_ALIENATION_DOC).size() == 0) {
                addActionError(" Should attach a Document !");
                return SUCCESS;
            }
            //delete Documents
            deleteDocument();

            landApplication.setDocumentList(getUploadedfileList(ModuleType.ATTACH_ALIENATION_DOC));
            logger.debug("Sign Or Not : {}", signOrNot);
            landApplicationManagementService.saveAttachedAlienationDoc(landApplication, signOrNot, user);
            addActionMessage("Signed Alienation Document attached successfully !");
            return SUCCESS;

        } catch (Exception e) {
            e.printStackTrace();
            addActionError("Signed Alienation Document attachment failed!");
            return ERROR;
        }

    }

    public String saveLeasePaymentDetail() {
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            logger.debug("saveLeasePaymentDetail : {}", user.getUsername());
            logger.debug("\n\n\n\n\nsaveLeasePaymentDetail : {}", user);

            //logger.debug("leasePeriod : {}", landApplication.getAlienationDetails().getLeaseDetail().getLeasePeriod());
            landApplicationManagementService.saveLeasePaymentDetail(landApplication, user);

            logger.debug("\n\n\n\n\nsaveLeasePaymentDetail : {}", user);

            addActionMessage("Lease Payment Detail Saved successfully!");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String completeInterviews() {
        isComplete = true;
        return addDetailedLandApplication();
    }

    public String initApplicationApprove() {
        landApplicationList = landApplicationManagementService.getPendingApprovalInitLandApplicationList(user);
        logger.debug("Select init application {} List for  Approval ", landApplicationList.size());
        return SUCCESS;
    }

    public String initApplicationToBeEdit() {
        landApplicationList = landApplicationManagementService.getPendingEditInitLandApplicationList(user);
        logger.debug("Select init application {} List for  Approval ", landApplicationList.size());
        return SUCCESS;
    }

    public String loadPaymentAgreementList() {
        try {
            logger.debug("Loading loadPaymentAgreementList application list");
            landApplicationList = landApplicationManagementService.getApplicationsByWorkFlowItemId(user, AppConstants.PLC_APPROVED);
            logger.debug("Select init application {} List for  Agreement ", landApplicationList.size());
            return SUCCESS;
        } catch (Exception e) {
            addActionError(getText("unable_to_find_agreement"));
            logger.error(e.getMessage());
            return ERROR;
        }
    }

    //Agreement
    public String initApplicationAgreement() {
        try {
            logger.debug("Loading Agreement application list");
            EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.UNSIGNED_PRINTED_ALIENATION_DOCUMENT);
            landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
            logger.debug("Select init application {} List for  Agreement ", landApplicationList.size());
            return SUCCESS;
        } catch (Exception e) {
            addActionError(getText("unable_to_find_agreement"));
            logger.error(e.getMessage());
            return ERROR;
        }
    }

    //Agreement
    public String initFinalAgreement() {
        try {
            logger.debug("Loading Final Agreement application list");
            landApplicationList = landApplicationManagementService.getApplicationsByState(user,
                    WorkflowTask.CONDITION_SATISFIED);
            logger.debug("Select init application {} List for Final  Agreement ", landApplicationList.size());
            return SUCCESS;
        } catch (Exception e) {
            addActionError(getText("unable_to_find_agreement"));
            logger.error(e.getMessage());
            return ERROR;
        }
    }

    public String initIssueAgreement() {
        try {
            logger.debug("Loading Agreement application list");
            landApplicationList = landApplicationManagementService.getApplicationsByState(user,
                    WorkflowTask.CONDITION_SATISFIED);
            logger.debug("Select init application {} List for  Agreement ", landApplicationList.size());
            return SUCCESS;
        } catch (Exception e) {
            addActionError(getText("unable_to_find_agreement"));
            logger.error(e.getMessage());
            return ERROR;
        }
    }


    public String signedAgreementList() {
        try {
            logger.debug("Loading Agreement application list");
            landApplicationList = landApplicationManagementService.getApplicationsByState(user,
                    WorkflowTask.SIGNED_PRINTED_ALIENATION_DOCUMENT);
            logger.debug("Select init application {} List for  Agreement ", landApplicationList.size());
            return SUCCESS;
        } catch (Exception e) {
            addActionError(getText("unable_to_find_agreement"));
            logger.error(e.getMessage());
            return ERROR;
        }
    }

    public String detailApplicationApprove() {
        landApplicationList = landApplicationManagementService.getPendingApprovalDetailLandApplicationList(getUser());
        return SUCCESS;
    }

    public String homeSLC() {
        landApplicationList = landApplicationManagementService.getApplicationsByStateSetAndUser(user);
        return SUCCESS;
    }

    public String detailApplicationFinalized() {
        editMode = 8;
        EnumSet<WorkflowTask> stateSet = EnumSet.of(
                WorkflowTask.DETAILED_FORM_FINALIZED,
                WorkflowTask.LAND_ALLOCATION_REJECTED,
                WorkflowTask.LAND_ALLOCATED
        );
        landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
        return SUCCESS;
    }

    //load for lo to add/edit
    public String loadApplicationToComplete() {
        editMode = 11;
        EnumSet<WorkflowTask> stateSet = EnumSet.of(
                WorkflowTask.LAND_ALLOCATION_APPROVED,
                WorkflowTask.ACCEPTED_AND_COMPLETED,
                WorkflowTask.REJECTED_AND_ARCHIVED,
                WorkflowTask.NOT_SUBMITTED_AND_ARCHIVED);
        landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
        return SUCCESS;
    }

    //load to ords to approve
    public String getCompletedApplicationList() {
        logger.debug("Load detailed Land Application List to be approved : {} ", user.getUsername());
        //Find All Active Land Apps with States in WorkflowTask
        //Load all apps to be completed for current user group   (State.DETAILED_FORM_DATA_ENTRY)
        try {
            EnumSet<WorkflowTask> stateSet = EnumSet.of(
                    WorkflowTask.ACCEPTED_AND_COMPLETED,
                    WorkflowTask.REJECTED_AND_ARCHIVED,
                    WorkflowTask.NOT_SUBMITTED_AND_ARCHIVED);
            landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String approveCompletedApplication() {
        logger.debug("Approve completed application : {}", user.getUsername());
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.approveCompletedApplication(landApplication, comment, user);
            addActionMessage("Approve Completed application Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  approving approving  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String rejectCompletedApplicationByDS() {
        logger.debug("Approve completed application : {}", user.getUsername());
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.rejectCompletedApplicationByDS(landApplication, comment, user);
            addActionMessage("Reject Completed application Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  approving approving  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String approveLandAllocationWithByPass() {
        logger.debug("Approve Land Allocation With ByPass Complete : {}", user.getUsername());
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.approveLandAllocationWithByPass(landApplication, comment, user);
            addActionMessage("Approve Land Allocation Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  Approve Land Allocation With ByPass Complete  : {}", e);
            addActionError("Approve Land Allocation Fail !");
            return ERROR;
        }
        return SUCCESS;
    }


    public String loadInterviewPage() {
        editMode = 4;
        EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.DETAILED_FORM_APPROVED,
                WorkflowTask.INTERVIEW_DATA_ENTRY);
        landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
        return SUCCESS;
    }

    public String loadObjectionHandlingPage() {
        editMode = 5;
        EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.INTERVIEW_COMPLETED,
                WorkflowTask.OBJECTION_DATA_ENTRY);
        landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
        return SUCCESS;
    }

    public String approveObjectionsAppListPageLoad() {
        editMode = 6;
        landApplicationList = landApplicationManagementService.getApplicationsByState(user,
                WorkflowTask.OBJECTION_HANDLING_COMPLETED);
        return SUCCESS;
    }

    public String loadAppListToBeFinalized() {
        logger.debug("Complete Land Application list to be completed : {}", user.getUsername());
        editMode = 7;
        EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.INTERVIEW_COMPLETED,
                WorkflowTask.OBJECTION_HANDLING_APPROVED);
        landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);

        return SUCCESS;
    }


    public String approveObjections() {
        logger.debug("Approve objections : {}", user.getUsername());
        try {
            landApplicationManagementService.approveObjections(landApplication, comment, WorkflowTask.OBJECTION_HANDLING_APPROVED, user);
            addActionMessage("objections Approved Successfully!");
        } catch (Exception e) {
            addActionError("Objections Approved Fail!");
            logger.debug("Error in  approving objectionsn  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String completeApplication() {
        logger.debug("Complete Land Application : {} ", user.getUsername());
        try {
            landApplicationManagementService.completeLandApplication(applicationId, user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String initApproveApplication() {
        try {
            logger.debug("init Approve Application");
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);

            if (landApplication.getPreferredAlienationMethod() != null) {
                alienationType = landApplication.getPreferredAlienationMethod().getId();
            }
            populateAlienationMethodSet(alienationType);
            if (isNewAlienation()) {
                populateAlienationMethodIds();
            }
            if (landApplication.getAlienationDetails() != null) {
                if (landApplication.getAlienationDetails().getLand() != null) {
                    landList.add(landApplication.getAlienationDetails().getLand());
                }
                if (landApplication.getAlienationDetails().getLandList() != null) {
                    landList.addAll(landApplication.getAlienationDetails().getLandList());
                }
            }

            holder = landApplication.getHolder();
            contacts = holder.getContacts();
            contactPerson = holder.getContactPerson();
            children = holder.getChildren();
            populateBasicLists();
            dsDivisionId = holder.getGnDivision().getDsDivision().getId();
            districtId = holder.getGnDivision().getDsDivision().getDistrictId();
            gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(dsDivisionId, language, user);
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(districtId, language, user);
            setDsDivisionsSelectedList();

        } catch (Exception e) {
            addActionError(getText("unable_to_find_organization"));
            e.printStackTrace();
            logger.error(e.getMessage());
            return ERROR;
        }
        editMode = 2;
        return getAlienationTypeName() + SUCCESS;
    }

    public String approveInitApplication() {
        try {
            Map<String, String> slcMessages;

            slcMessages = landApplicationManagementService.approveInitLandApplication(applicationId, comment, user);

            logger.debug("Approved Init Land Application by: {} Land Application id is : {}", user.getUsername(), applicationId);

            landApplicationList = landApplicationManagementService.getPendingApprovalInitLandApplicationList(user);
            addActionMessage(getText("approve_success_init_application"));
            String landRefNumber = null;
            String slcPassword = null;
            String slcEmail = null;
            String slcMobile = null;
            String smsSuccess = null;

            if (slcMessages != null) {
                landRefNumber = slcMessages.get("slcReferenceNo");
                slcPassword = slcMessages.get("slcPassword");
                slcEmail = slcMessages.get("slcEmail");
                slcMobile = slcMessages.get("slcMobile");
                smsSuccess = slcMessages.get("smsSuccess");
            }

            if ((landRefNumber != null) && (!landRefNumber.isEmpty())) {
                addActionMessage(getText("initial_application_reference_no_is.label") + " " + landRefNumber);
            }

            if ((slcPassword != null) && (!slcPassword.isEmpty())) {
                addActionMessage(getText("slc_password_is.label") + " " + slcPassword);
            }

            if ((slcEmail == null) || (slcEmail.isEmpty())) {
                addActionMessage(getText("email_not_sent.label"));
            }

            if ((slcMobile == null) || (slcMobile.isEmpty())) {
                logger.debug("Mobile: {}", slcMobile);
                addActionMessage(getText("sms_not_sent.label"));
            } else if (smsSuccess.equals("false")) {
                addActionMessage(getText("sms_not_sent_failure.label"));
            }

        } catch (Exception e) {
            addActionError(getText("unable_to_approve_application"));
            logger.error(e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }

    //get approved list
    public String getAgreementType() {
        try {
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            holder = landApplication.getHolder();
            contacts = holder.getContacts();
            if (landApplication.getPreferredAlienationMethod() != null && landApplication.getPreferredAlienationMethod().getId() == 5) {
                contactPerson = holder.getContacts();
            }
            int dsId = landApplication.getAlienationDetails().getLand().getGnDivision().getDsDivision().getId();
            User dsUser = userManager.getUsersByRoleDS("ORDS", dsId, user).iterator().next();
            if (dsUser != null) {
                ordsName = dsUser.getFullName();
            }
            initApplicationId = applicationId;
            setDsDivisionsSelectedList();
            populateBasicLists();
            logger.debug("Agreement type is :{}", getAlienationTypeName());
            int id = landApplication.getAlienationDetails().getAlienationMethod().getId();
            return getAlienationTypeNameById(id) + SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            addActionError(getText("unable_to_find_agreement"));
            logger.error(e.getMessage());
            return ERROR;
        }
    }

    public String rejectInitApplication() {
        try {
            logger.debug("reject Comment - {}", comment);
            landApplicationManagementService.rejectInitLandApplication(applicationId, comment, user);
            logger.debug("Reject Init Land Application by :{}  Land Application id is : {}", user.getUsername(), applicationId);
            landApplicationList = landApplicationManagementService.getPendingApprovalInitLandApplicationList(user);
            addActionMessage(getText("reject_success_init_application") /*+ " --  Reference Number is : " + landApplication.getRefNumber()*/);

        } catch (Exception e) {
            addActionError(getText("unable_to_reject_application"));
            logger.error(e.getMessage());
            e.printStackTrace();
            return ERROR;
        }
        return SUCCESS;
    }

    //send mail init Application
    public String sendMailInitApplication() {
        try {
            logger.error("send Mail Init Application {}", applicationId);
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            logger.debug("Send mail Init Land Application by :{}  Land Application id is : {}", user.getUsername(),
                    applicationId);
            String comment = "Comment";
            String email = landApplication.getHolder().getContacts().getEmail();
            logger.error("send Mail Init Application Email {}", email);
            if (sendMail(comment, email)) {
                addActionMessage(getText("mail_send_success.label"));
            } else {
                addActionError(getText("mail_send_fail.label"));
            }
            landApplicationList = landApplicationManagementService.getPendingApprovalInitLandApplicationList(user);

        } catch (Exception e) {
            e.printStackTrace();
            addActionError(getText("mail_send_fail.label"));
            logger.error(e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }

    private boolean sendMail(String comment, String email) {
        String msg = "Dear Applicant, \n" +
                comment +
                "\n\n" +
                "Regards,\n" +
                "Divisional Secretery,\n" +
                user.getDsDivisions().iterator().next().getEnDivisionName();

        return mailSenderService.sendMail("from@no-spam.com", email, "Initial Land Application" +
                "", msg);
    }

    public String editLandApplicationPageLoad() { //both initial and detailed
        logger.debug("edit Land Application Page Load");
        try {
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            initApplicationId = landApplication.getInitApplicationId();
            if (landApplication.getPreferredAlienationMethod() != null) {
                alienationType = landApplication.getPreferredAlienationMethod().getId();
            }
            populateAlienationMethodSet(alienationType);

            //display Alienation Method list
            if (isNewAlienation()) {
                populateAlienationMethodIds();
            }

            loadLandList();

            holder = landApplication.getHolder();
            contacts = landApplication.getHolder().getContacts();
            contactPerson = landApplication.getHolder().getContactPerson();
            //gnDivisionId = holder.getGnDivision().getGnDivisionId();
            dsDivisionId = holder.getGnDivision().getDsDivision().getId();
            districtId = holder.getGnDivision().getDsDivision().getDistrictId();

            children = holder.getChildren();
            setDsDivisionsSelectedList();
            populateBasicLists();
            gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(dsDivisionId, language, user);
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(districtId, language, user);

            if (initApplicationId > 0) { //detailed app
                if (landApplication.getAlienationDetails() != null &&
                        landApplication.getAlienationDetails().getLand() != null) {
                    logger.debug("----------------------------------------------------initAppid {}", initApplicationId);

                }
                populateUploadedFiles(landApplication.getId(), ModuleType.DETAILED_APP);
                findDocumentCategoryList(ModuleType.INITIAL_APP);
                return getAlienationTypeName() + "detail" + SUCCESS;
            } else {  //initial app
                return getAlienationTypeName() + "init" + SUCCESS;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ERROR;
        }

    }

    private void setDsDivisionsSelectedList() {
        Set<DSDivision> dsDivisionList = landApplication.getDsDivisions();
        dsDivisionsSelectedList = new HashMap<Integer, String>();
        for (DSDivision ds : dsDivisionList) {
            String val = Long.toString(ds.getCode());    //TODO : remove this
            if (AppConstants.ENGLISH.equals(language)) {
                val = ds.getEnDivisionName();
            } else if (AppConstants.SINHALA.equals(language)) {
                val = ds.getSiDivisionName();
            } else if (AppConstants.TAMIL.equals(language)) {
                val = ds.getTaDivisionName();
            }
            dsDivisionsSelectedList.put(ds.getId(), val);
        }
        logger.debug("size of list :{}", dsDivisionsSelectedList.size());
    }

    //TODO : to be reviewed
    public String approvedInitApplicationFormsList() {
        alienationTypeList = alienationManagementService.getAllAlienationMethods(language, user);
        logger.debug("Alienation Type List............ {} ", alienationTypeList.size());
        if (alienationType == 0) { // Load all apps
            landApplicationList = landApplicationManagementService.getApprovedApplicationList(user);
            logger.debug("Loading selected application list{}", landApplicationList.size());
        } else { //todo if not new AM
            landApplicationList = landApplicationManagementService.getApplicationListByStateAndAM(user,
                    LandApplication.State.INITIAL_APPLICATION_APPROVED, alienationType);
        } //todo for new AM
        logger.debug("Select {} item to enter detail information : {}", landApplicationList.size());
        return SUCCESS;
    }

    //for public access
    public String shortListedCandidates() {
        try {
            alienationTypeList = alienationManagementService.getAllAlienationMethods("en");
            logger.debug("Alienation Type List............ {} ", alienationTypeList.size());
            logger.debug("Alienation Type  {} ", alienationType);
            EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.INTERVIEW_COMPLETED,
                    WorkflowTask.OBJECTION_DATA_ENTRY);
            landApplicationList = landApplicationManagementService.getShortListedCandidates(stateSet, alienationType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }


    public String preliminaryCandidatesList() {
        try {
            logger.debug("preliminary Candidates List ");
            EnumSet<WorkflowTask> stateSet = EnumSet.of(WorkflowTask.INTERVIEW_COMPLETED,
                    WorkflowTask.OBJECTION_DATA_ENTRY);
            landApplicationList = landApplicationManagementService.getApplicationsByStateSet(user, stateSet);
            populateBasicLists();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    public String shortListedCandidatesList() {
        try {
            logger.debug("shortListed Candidates List");
            landApplicationList = landApplicationManagementService.getApplicationsByWorkflowState(user, WorkflowTask.DETAILED_FORM_FINALIZED);
            populateBasicLists();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }

    //load SLC ApplicationList to Enter Detail
    public String loadDetailApplicationListBySLC() {
        //find all applications of user (applicant) where the initialstatus is not CLOSED
        landApplicationList = landApplicationManagementService.getApplicationsByStateSetAndUser(user);
        logger.debug("load Enter Detail Application List By SLC  {} ", user);
        logger.debug("Select {} item to enter detail information By SLC : {}", landApplicationList.size());
        return SUCCESS;
    }

    public String initAlienationApplicationReport() {
        alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);
        landApplicationList = landApplicationManagementService.getPendingApprovalInitLandApplicationList(user);
        logger.debug("Select {} item to enter detail information : {}", alienationMethodList.size());
        return SUCCESS;
    }

    public String searchInitApplications() {
        alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);
        //todo remove alienationMethod attribute, use AlienationType instead, Please do not duplicate
        landApplicationList = landApplicationManagementService.getLandApplicationListByAlienationType(alienationMethod, user);
        logger.debug("Select {} item to enter detail information : {}", landApplicationList.size());
        return SUCCESS;
    }

    //load application details to  Acknowledgement
    public String getAcknowledgementDetail() {
        try {
            logger.debug("init Detail Application {} - ", user.getUsername());
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);

            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error in Acknowledgement detail  land application  : {}", e);
            e.printStackTrace();
            return ERROR;
        }

    }

    public String editCompleteApplication() {
        String res = initDetailApplication();
        editMode = AppConstants.COMPLETE_EDIT_MODE;
        return res;
    }

    //load land details page for add detail, search, approve, reports pages
    public String initDetailApplication() {
        try {
            logger.debug("init Detail Application {} - ", user.getUsername());
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);

            if (landApplication.getAlienationDetails() != null) {
                if (landApplication.getAlienationDetails().getLand() != null) {
                    landList.add(landApplication.getAlienationDetails().getLand());
                    logger.debug("adding land to land tree");
                }
                if (landApplication.getAlienationDetails().getLandList() != null) {
                    landList.addAll(landApplication.getAlienationDetails().getLandList());
                    logger.debug("adding land List to land tree");
                }
            }


            if (landApplication.getPreferredAlienationMethod() != null) {
                alienationType = landApplication.getPreferredAlienationMethod().getId();
            }

            populateAlienationMethodSet(alienationType);
            populateAlienationMethodIds();
            findDocumentCategoryList(ModuleType.INITIAL_APP);
            populateUploadedFiles(landApplication.getId(), ModuleType.DETAILED_APP);

            //load land id
            if (landApplication.getAlienationDetails() != null && landApplication.getAlienationDetails().getLand() != null) {
                landId = landApplication.getAlienationDetails().getLand().getId();

            }

            holder = landApplication.getHolder();
            logger.debug("holder id -----  {}", holder.getId());

            contacts = holder.getContacts();
            contactPerson = holder.getContactPerson();
            dsDivisionId = holder.getGnDivision().getDsDivision().getId();
            districtId = holder.getGnDivision().getDsDivision().getDistrictId();

            children = holder.getChildren();

            //TODO: to be reviewed
            initApplicationId = applicationId;

            setDsDivisionsSelectedList();
            populateBasicLists();
            gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(dsDivisionId, language, user);
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(districtId, language, user);

            //set public objection
            setPublicObjection();

            if (AppConstants.ORDS_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.PLC_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.LCG_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.ORLP_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.MA_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.ALC_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.DLC_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.LC_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.APLC_USER_ROLE.equals(user.getRole().getId()) ||
                    AppConstants.DPLC_USER_ROLE.equals(user.getRole().getId())
                    ) {
                editMode = AppConstants.APPROVE_MODE;
            } else if (AppConstants.LO_USER_ROLE.equals(user.getRole().getId()) || AppConstants.ORIP_USER_ROLE.equals(user.getRole().getId())) {
                if (landApplication.getWorkflowItem() != null) {
                    WorkflowTask workflowTask = landApplication.getWorkflowItem().getWorkflowTask();
                    if (workflowTask == WorkflowTask.INTERVIEW_COMPLETED ||
                            workflowTask == WorkflowTask.OBJECTION_DATA_ENTRY ||
                            workflowTask == WorkflowTask.DETAILED_FORM_FINALIZED ||
                            workflowTask == WorkflowTask.LAND_ALLOCATED ||
                            workflowTask == WorkflowTask.LAND_ALLOCATION_REJECTED ||
                            workflowTask == WorkflowTask.LAND_ALLOCATION_APPROVED ||
                            workflowTask == WorkflowTask.ACCEPTED_AND_COMPLETED ||
                            workflowTask == WorkflowTask.REJECTED_AND_ARCHIVED ||
                            workflowTask == WorkflowTask.ACCEPTED_AND_COMPLETED_APPLICATION_REJECTED ||
                            workflowTask == WorkflowTask.REJECT_REJECTED_AND_ARCHIVED_APPLICATION ||
                            workflowTask == WorkflowTask.REJECT_NOT_SUBMITTED_APPLICATION) {
                        editMode = AppConstants.APPROVE_MODE;
                    }
                    //orip users for rejection
                    if (AppConstants.ORIP_USER_ROLE.equals(user.getRole().getId()) && workflowTask == WorkflowTask.REJECTED) {
                        editMode = AppConstants.APPROVE_MODE;
                    }

                    //set otherMode value for objection handle state for Doc Upload
                    if (workflowTask == WorkflowTask.INTERVIEW_COMPLETED ||
                            workflowTask == WorkflowTask.OBJECTION_DATA_ENTRY) {
                        otherMode = AppConstants.OBJECTION_MODE;
                        objectionDisabled = !(landApplicationManagementService.isObjectionsEnabled(landApplication));
                    } else {
                        otherMode = 0;
                    }
                }
            }

            logger.debug("size of the land list for approving land app {} ", landList.size());
            logger.debug("initDetailApplication successfull {}", getAlienationTypeName());
            return getAlienationTypeName() + SUCCESS;
        } catch (Exception e) {
            logger.error("Error in populating detail  land application  : {}", e);
            e.printStackTrace();
            return ERROR;
        }
    }

    private void setPublicObjection() {
        List<Objection> publicObjectionList = objectionManagementService.getObjectionByApplicationId(applicationId);
        if (publicObjectionList != null && publicObjectionList.size() > 0) {
            slcObjections = "";
            for (Objection objection : publicObjectionList) {
                slcObjections += objection.getObjection() + "\n\n";
            }
        }
    }

    public String loadAttachAlienationDoc() {
        try {
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            findDocumentCategoryList(ModuleType.INITIAL_APP);
            populateUploadedFiles(landApplication.getId(), ModuleType.ATTACH_ALIENATION_DOC);
            return SUCCESS;

        } catch (Exception e) {
            logger.error("Error in load Attach Alienation Doc  : {}", e);
            e.printStackTrace();
            return ERROR;
        }
    }

    public String getLetterType() {
        String res = initDetailApplication();
        if (res.equals(ERROR)) {
            return ERROR;
        } else {
            logger.debug("getLetterTypel {}", res + (landApplication.getLandUsage().getEnUsageName()));
            return res + (landApplication.getLandUsage().getId());
        }
    }

    private void populateDistricts() {
        try {
            logger.debug("Populate District Lists by {}", user.getUsername());
            if (userProvinceId > 0) {
                districtList = districtDAO.getAllDistrictNamesByProvinceId(userProvinceId, language, user);
            } else {
                districtList = districtDAO.getAllDistrictNames(language, user);
            }
            dsDivisionList = new HashMap<Integer, String>();

        } catch (Exception ex) {
            ex.printStackTrace();
            logger.debug("TryCatchError", ex.getMessage());
        }
    }

    private void populateBasicLists() {
        try {
            Map<Integer, String> temp = new HashMap<Integer, String>();
            Set<LandUsage> landUsage;

            if (alienationType == AppConstants.LAND_PERMIT || alienationType == 0) {
                landUsage = alienationManagementService.getAlienationMethodById(AppConstants.LAND_PERMIT, user)
                        .getLandUsage();
                landUsage.addAll(alienationManagementService.getAlienationMethodById(AppConstants.SHORT_TERM_LEASE, user)
                        .getLandUsage());
                landUsage.addAll(alienationManagementService.getAlienationMethodById(AppConstants.LONG_TERM_LEASE, user)
                        .getLandUsage());
            } else {
                landUsage = alienationManagementService.getAlienationMethodById(alienationType, user)
                        .getLandUsage();
            }

            for (LandUsage lu : landUsage) {
                String val = Long.toString(lu.getId());
                if (AppConstants.ENGLISH.equals(language)) {
                    val = lu.getEnUsageName();
                } else if (AppConstants.SINHALA.equals(language)) {
                    val = lu.getSiUsageName();
                } else if (AppConstants.TAMIL.equals(language)) {
                    val = lu.getTaUsageName();
                }
                temp.put(lu.getId(), val);
            }

            DSDivision userDS = null;
            if (user != null && !user.getDsDivisions().isEmpty()) {
                userDS = user.getDsDivisions().iterator().next();
            } else {
                int userDSId = 0;
                String userGroup = (String) session.get(AppConstants.SESSION_USER_GROUP);
                if (AppConstants.SESSION_ONLINE_USER_GROUP.equals(userGroup)) {
                    userDSId = (Integer) session.get(AppConstants.SESSION_ONLINE_USER_DS);
                    if (userDSId != 0) {
                        userDS = dsDivisionDAO.getDSDivisionByPK(userDSId);
                    }
                } else if (AppConstants.ORIP_USER_ROLE.equals(user.getRole().getId())) {
                    logger.debug("\n\n\n user {}", userDSId);
                }
            }

            if (userDS != null) {
                //gnDivisionList = gnDivisionDAO.getGNDivisionNamesByDsDivisionId(userDS.getId(), language, user);
                //gnDivisionList = new HashMap<Integer, String>();
                logger.debug("received user ds id {}", userDS.getId());
                if (AppConstants.ENGLISH.equals(language)) {
                    dsDivisionName = userDS.getEnDivisionName();
                    districtName = userDS.getDistrict().getEnDistrictName();
                } else if (AppConstants.SINHALA.equals(language)) {
                    dsDivisionName = userDS.getSiDivisionName();
                    districtName = userDS.getDistrict().getSiDistrictName();
                } else if (AppConstants.TAMIL.equals(language)) {
                    dsDivisionName = userDS.getTaDivisionName();
                    districtName = userDS.getDistrict().getTaDistrictName();
                }
            }

            purposeList = temp;

            if (userProvinceId > 0) {
                districtList = districtDAO.getAllDistrictNamesByProvinceId(userProvinceId, language, user);
            } else {
                districtList = districtDAO.getAllDistrictNames(language, user);
            }

            setDistrictListAll(districtDAO.getAllDistrictNames(language, user));
            //dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(userDistrictId, language, user);
            dsDivisionList = new HashMap<Integer, String>();
            gnDivisionList = new HashMap<Integer, String>();


        } catch (Exception e) {
            logger.debug("Error in populating lists   : {}", e);
            e.printStackTrace();
        }
    }

    public String addDetailLandApplication() {
        return SUCCESS;
    }

    private String getAlienationTypeNameById(int id) {
        String typeStr = "";
        switch (id) {
            case 1:
                typeStr = WebConstants.LAND_PERMIT;
                break;
            case 2:
                typeStr = WebConstants.LAND_GRANTS;
                break;
            case 3:
                typeStr = WebConstants.ANNUAL_LEASE;
                break;
            case 4:
                typeStr = WebConstants.LONG_TERM_LEASE;
                break;
            case 5:
                typeStr = WebConstants.RELEASE_TO_DEPARTMENT;
                break;
            case 6:
                typeStr = WebConstants.VESTING_ORDER;
                break;
            case 7:
                typeStr = WebConstants.OUT_RIGHT_GRANT;
                break;

        }
        logger.debug("getAlienationTypeNameBy Id : {} Name {}", id, typeStr);
        return typeStr;
    }

    private void populateAlienationMethodNames() {
        try {
            logger.debug("Populate Basic Lists of Land Details by {}", user.getUsername());
            alienationTypeList = new LinkedHashMap<Integer, String>();

            alienationTypeList.putAll(alienationManagementService.getAllAlienationMethods(language, user));
            findDocumentCategoryList(ModuleType.INITIAL_LAND);

            alienationMethodSet = new HashMap<Integer, String>();
            for (int i = 1; i < alienationTypeList.size(); i++) {
                alienationMethodSet.put(i, alienationTypeList.get(i));
            }

        } catch (Exception e) {
            logger.debug("Error: ", e.getMessage());
            e.printStackTrace();
        }
    }

    private String getAlienationTypeName() {
        String typeStr = "";
        if (isNewAlienation()) {
            typeStr = WebConstants.LAND_PERMIT;
            return typeStr;
        } else {
            switch (landApplication.getPreferredAlienationMethod().getId()) {
                case 1:
                    typeStr = WebConstants.LAND_PERMIT;
                    break;
                case 2:
                    typeStr = WebConstants.LAND_GRANTS;
                    break;
                case 3:
                    typeStr = WebConstants.ANNUAL_LEASE;
                    break;
                case 4:
                    typeStr = WebConstants.LONG_TERM_LEASE;
                    break;
                case 5:
                    typeStr = WebConstants.RELEASE_TO_DEPARTMENT;
                    break;
                case 6:
                    typeStr = WebConstants.VESTING_ORDER;
                    break;
                case 7:
                    typeStr = WebConstants.OUT_RIGHT_GRANT;
                    break;

            }
            logger.debug("edit mode : {}", editMode);
            return typeStr;
        }
    }

    public String landAlienationModuleHome() {
        logger.info("Land Alienation Module Home loaded ");
        return SUCCESS;
    }

    public String initOnlineLandAlienation() {
        //todo set Online user to SESSION_USER_BEAN in loading the fist page of online app
        gnDivisionList = new HashMap<Integer, String>();

        session.put(AppConstants.SESSION_ONLINE_USER_DS, onlineApplicantDsDivisionId);
        session.put(AppConstants.SESSION_USER_GROUP, AppConstants.SESSION_ONLINE_USER_GROUP);
        logger.debug("Online Applicant Ds DivisionId {} ", onlineApplicantDsDivisionId);

        return initLandAlienation();
    }

    public String initOnlineApplication() {
        //todo set Online user to SESSION_USER_BEAN in loading the fist page of online app
        gnDivisionList = new HashMap<Integer, String>();
        return initLandAlienation();
    }

    public String initLandAlienation() {
        try {
            //only applicable for GRANT type of Alienations
            if (alienationType == AppConstants.LAND_GRANT) {
                initGrantPage = true;
            }
            dsDivisionsSelectedList = new HashMap<Integer, String>();

            //Long Term Lease, Short Term Lease, Land Permits - same application form will be used.
            populateAlienationMethodSet(alienationType);

            populateBasicLists();

            logger.info("Start land alienation page load");
        } catch (Exception e) {
            logger.debug("Error e :{}", e);
            e.printStackTrace();
        }
        editMode = AppConstants.NEW_MODE;
        return SUCCESS;
    }

    public String searchPermit() {

        logger.debug("search land permits by user {}", user.getUsername());
        try {
            alienationList = alienationManagementService.searchPermitLands(user);
            populateBasicLists();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        return SUCCESS;
    }

    //populate permit details in land grant app
    public String populateInitLandGrantsApplication() {
        try {
            initGrantPage = false;
            dsDivisionsSelectedList = new HashMap<Integer, String>();
            logger.debug("load alienation detail of permit land : {}", permitNo);
            Alienation alienation = alienationManagementService.getActiveApprovedAlienationByPermitNo(permitNo, user);
            if (alienation != null) {

                if (alienation.getStatus().equals(Alienation.State.PENDING)) {
                    initGrantPage = true;
                    addActionError(getText("requested_entry_not_available.label"));
                } else {
                    holder = new Holder();
                    holder.setName(alienation.getHolder().getName());
                    holder.setDateOfBirth(alienation.getHolder().getDateOfBirth());
                    holder.setSpouse(alienation.getHolder().getSpouse());
                    holder.setRegistrationNumberOrNIC(alienation.getHolder().getRegistrationNumberOrNIC());
                    holder.setGender(alienation.getHolder().getGender());
                    contacts = alienation.getHolder().getContacts();
                    populateBasicLists();
                    editMode = 0;
                    logger.info("Start land alienation page load");
                }
            } else {
                initGrantPage = true;
                addActionError(getText("requested_entry_not_available.label"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            initGrantPage = true;
            addActionError(getText("requested_entry_not_available.label"));
            logger.debug("Error e :{}", e);
        }

        return SUCCESS;
    }

    public String initLandAlienationMethods() {
        logger.info("Start land alienation methods");
        return SUCCESS;
    }

    private Set<DSDivision> populateDSDivisions() {
        Set<DSDivision> dsDivisionList = new HashSet<DSDivision>();
        if (dsDivisionsSelected != null) {
            for (int ds : dsDivisionsSelected) {
                dsDivisionList.add(dsDivisionDAO.getDSDivisionByPK(ds));
            }
        }
        return dsDivisionList;
    }

    private List<AlienationMethod> populateAlienationMethods() {
        logger.debug("populating AM List");
        List<AlienationMethod> amList = new ArrayList<AlienationMethod>();
        if (alienationMethodSelectedList != null) {
            for (String am : alienationMethodSelectedList) {
                //TODO : get from service
                logger.debug("AM ID {} ", am);
                amList.add(alienationManagementService.getAlienationMethodById(Integer.parseInt(am), user));
            }
        }
        return amList;
    }

    private void populateAlienationMethodIds() {
        logger.debug("populating AM List");
        amSelectedList = new HashMap<Integer, String>();

        if (landApplication.getAlienationMethods() != null && landApplication.getAlienationMethods().size() != 0) {
            for (AlienationMethod am : landApplication.getAlienationMethods()) {
                amSelectedList.put(am.getId(), am.getEnName());
            }
        }
    }

    //TODO to be refactor
    public void populateAlienationMethodSet(int amId) {
        alienationMethodList = alienationManagementService.getAllAlienationMethods(language, user);
        alienationMethodSet = new HashMap<Integer, String>();

        if (amId == 0 || amId == 1 || amId == 3 || amId == 4) {  //0 - new alienation before selecting AM to APP
            alienationMethodSet.put(1, alienationMethodList.get(1));
            alienationMethodSet.put(3, alienationMethodList.get(3));
            alienationMethodSet.put(4, alienationMethodList.get(4));
        } else if (amId == 5 || amId == 6) {
            alienationMethodSet.put(5, alienationMethodList.get(5));
            alienationMethodSet.put(6, alienationMethodList.get(6));
        }
    }

    public String approveDetailedApplication() {
        logger.debug("Approve Land Application : {}", user.getUsername());
        try {
            landApplicationManagementService.approveDetailedLandApplication(applicationId, comment, user);
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            addActionMessage(getText("approve_success_detail_application") + " --  Reference Number is : " + landApplication.getRefNumber());

        } catch (Exception e) {
            logger.debug("Error in  approving land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String rejectDetailedApplication() {
        logger.debug("Reject Land Application at interview, : {} ", user.getUsername());
        try {
            landApplicationManagementService.rejectDetailedLandApplication(applicationId, comment, user);
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            addActionMessage(getText("reject_success_detail_application") + " --  Reference Number is : " + landApplication.getRefNumber());

        } catch (Exception e) {
            logger.debug("Error in  rejecting land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String finalizeApplication() {
        logger.debug("Finalize Land Application : {} ", user.getUsername());
        try {
            landApplicationManagementService.finalizeApplication(landApplication, comment, user);
            addActionMessage("Alienation Application Finalized Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  finalizing the land application  : {}", e);
            e.printStackTrace();
            return ERROR;
        }
        return SUCCESS;
    }

    public String approveApplication() {
        logger.debug("Approve Land Application : {}", user.getUsername());
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.approveLandApplication(landApplication, comment, user);
            addActionMessage("Alienation Application Approved Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  approving land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String approveApplicationByLC() {
        logger.debug("Approve Land Application : {}", user.getUsername());
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.approveLandApplicationByLC(landApplication,
                    WorkflowTask.ALIENATION_APPROVED_BY_LC, comment, user);
            addActionMessage("Alienation Application Approved Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  approving land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String recommendApplicationByLC() {
        logger.debug("Approve Land Application : {}", user.getUsername());
        try {
            landApplication.setDocumentList(getUploadedfileList(ModuleType.DETAILED_APP));
            landApplicationManagementService.approveLandApplicationByLC(landApplication,
                    WorkflowTask.APPROVED, comment, user);
            addActionMessage("Alienation Application Approved Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  approving land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }


    public String approveSignDocApplication() {
        logger.debug("Approve Sign Doc Application : {}", user.getUsername());
        try {
            landApplicationManagementService.approveSignDocApplication(landApplication, comment, user);
            addActionMessage("Alienation Application Approved Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  approving sign doc land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String rejectAttachedAlienationDoc() {
        logger.debug("Reject Sign Doc Application : {}", user.getUsername());
        try {
            landApplicationManagementService.rejectSignDocApplication(landApplication, comment, user);
            addActionMessage("Alienation Application Successfully Reject!");
        } catch (Exception e) {
            logger.debug("Error in  rejecting sign doc land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String rejectApplication() {
        logger.debug("Reject Land Application : {} ", user.getUsername());
        try {
            landApplicationManagementService.rejectLandApplication(applicationId, comment, user);
            addActionMessage("Alienation Application Rejected Successfully!");
        } catch (Exception e) {
            logger.debug("Error in  rejecting land application  : {}", e);
            return ERROR;
        }
        return SUCCESS;
    }

    public String loadAppList() {
        logger.debug("Loading detailed application list");
        landApplicationList = landApplicationManagementService.getApplicationsByState(user,
                WorkflowTask.DETAILED_FORM_FINALIZED);
        return SUCCESS;
    }

    public String loadSelectedAppList() {
        logger.debug("Loading selected application list");
        landApplicationList = landApplicationManagementService.getSelectedLandApplicationListByAlienationType(alienationType, user);

        logger.debug("Loading selected application list{}", landApplicationList.size());
        alienationTypeList = alienationManagementService.getAllAlienationMethods(language, user);
        logger.debug("Loading selected application list{}", alienationTypeList.size());
        return SUCCESS;
    }

    public String loadAppListToSearch() {
        logger.debug("Loading full application list");
        try {
            logger.debug("Loading full application list dsDivisionId {}", dsDivisionId);
            logger.debug("Loading full application list districtId {}", districtId);
            if (dsDivisionId == 0) {
                if (districtId == 0) {
                    landApplicationList = landApplicationManagementService.getApplicationList(user);
                } else {
                    logger.debug("search By DistrictId {} ", districtId);
                    landApplicationList = landApplicationManagementService.searchApplicationsByDistrictId(districtId, user);
                }
            } else {
                logger.debug("search applications By DS {} ", dsDivisionId);
                landApplicationList = landApplicationManagementService.searchApplicationsByDsId(dsDivisionId, user);
            }
            populateDistricts();
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(districtId, language, user);

        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("Error in  Loading full application list Search  : {}", e);
        }
        return SUCCESS;
    }

    public String searchApplicationByPersonName() {
        logger.debug("search Application By Person Name {} by {}", searchText, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            landApplicationList.addAll(landApplicationManagementService.searchApplicationsOfDSDivisionByPersonName(searchText, user));
            populateDistricts();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchText = "";
        return SUCCESS;
    }

    public String searchApplicationByNIC() {
        logger.debug("search Application By NIC {} by {}", searchText, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            landApplicationList.addAll(landApplicationManagementService.searchApplicationsOfDSDivisionByNIC(searchText, user));
            populateDistricts();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchText = "";
        return SUCCESS;
    }

    //todo: move these two to service layer and call from both workflow service and applicationservice
    public String getApprovedInitApplications() {
        landApplicationList = landApplicationManagementService.getInitialApplicationsByState(user,
                LandApplication.State.INITIAL_APPLICATION_APPROVED);
        return SUCCESS;
    }

    public String getRejectedInitApplications() {
        landApplicationList = landApplicationManagementService.getInitialApplicationsByState(user,
                LandApplication.State.INITIAL_APPLICATION_REJECTED);
        return SUCCESS;
    }

    private boolean isNewAlienation() {
        if (landApplication.getAlienationMethods() != null && landApplication.getAlienationMethods().size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    public String generateLetterForApplication() {
        logger.debug("Generate Letter For Application id :{} by {}", applicationId, user.getUsername());
        try {

            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);

            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error in Generate Letter For Allocated Application  : {}", e);
            e.printStackTrace();
            return ERROR;
        }
    }

    public String saveDueDateAllocatedApplication() {
        logger.debug("Save Due Date Allocated Application id :{} by {}", applicationId, user.getUsername());
        try {
            if (applicationId > 0) {
                landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
                int count = (landApplication.getLetterCount() + 1);
                if (count > 2) {
                    addActionError(getText("letter_generated_fail.label"));
                } else {
                    landApplication.setDueDate(dueDate);
                    landApplication.setLetterCount(count);
                    landApplicationManagementService.updateDueDateLandApplication(landApplication, user);

                    addActionMessage(getText("letter_generated_success.label"));
                }

            } else {
                addActionError(getText("letter_generated_fail.label"));
            }

        } catch (Exception e) {
            e.printStackTrace();
            addActionError(getText("letter_generated_fail.label"));
            logger.error("error in saving due date : {}", e);
        }

        return SUCCESS;
    }

    //load Letter of confirmation
    public String generateLetterOfConfirmation() {
        try {
            logger.debug("generate Letter Of Confirmation {} - ", user.getUsername());
            landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
            int dsId = landApplication.getAlienationDetails().getLand().getGnDivision().getDsDivision().getId();
            User dsUser = userManager.getUsersByRoleDS("ORDS", dsId, user).iterator().next();
            if (dsUser != null) {
                ordsName = dsUser.getFullName();
            }

            return SUCCESS;
        } catch (Exception e) {
            logger.error("Error in generate Letter Of Confirmation  : {}", e);
            e.printStackTrace();
            return ERROR;
        }

    }

    public String saveSetUpAction() {
        logger.debug("Save SetUpAction Application id :{} by {}", applicationId, user.getUsername());
        try {
            if (applicationId > 0) {
                landApplication = landApplicationManagementService.getLandApplicationByIdUKey(applicationId, user);
                landApplicationManagementService.saveSetUpAction(landApplication, user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Save Set Up Action : {}", e);
        }

        addActionMessage("Condition Satisfied");
        return SUCCESS;
    }

    private void loadLandList() {
        logger.error("\n\n\n\nloadLandList ");

        if (landApplication.getAlienationDetails() != null) {
            logger.error("loadLandList  OK");
            if (landApplication.getAlienationDetails().getLand() != null) {
                landList.add(landApplication.getAlienationDetails().getLand());
            }
            if (landApplication.getAlienationDetails().getLandList() != null) {
                landList.addAll(landApplication.getAlienationDetails().getLandList());
                landChildList = landApplication.getAlienationDetails().getLandList();
            }
        }
    }

    public LandApplication getLandApplication() {
        return landApplication;
    }

    public String onlineApplicationDirectionPageLoad() {
        User onlineApplicant = userManager.getUserByUserName("onlineapplicant");
        districtList = districtDAO.getAllDistrictNames(language, onlineApplicant);
        dsDivisionList = new HashMap<Integer, String>();
        return SUCCESS;
    }

    public String loadAlienationsToSearch() {
        logger.debug("Loading full Alienation list");
        try {
            logger.debug("Loading full Alienation list dsDivisionId {}", dsDivisionId);
            logger.debug("Loading full Alienation list districtId {}", districtId);

            if (dsDivisionId == 0) {
                if (districtId == 0) {
                    logger.debug("Nothing Selected  but the user DS Divisions : {}  ", user.getDsDivisions());
                    landApplicationList = landApplicationManagementService.getApplicationsByState(user, WorkflowTask.CONDITION_SATISFIED);
                } else {
                    logger.debug("Only the district ID Selected {} ", districtId);
                    landApplicationList = landApplicationManagementService.getApplicationsByStateAndDistrict(user, WorkflowTask.CONDITION_SATISFIED, districtId);
                }
            } else {
                // search by DS
                logger.debug("DS Division Selected {} ", dsDivisionId);
                landApplicationList = landApplicationManagementService.getApplicationsByStateAndDsId(WorkflowTask.CONDITION_SATISFIED, dsDivisionId, user);
            }
            populateDistricts();
            populateAlienationMethodNames();
            dsDivisionList = dsDivisionDAO.getDSDivisionNamesByDistrictId(districtId, language, user);

        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("Error in  Loading full application list Search  : {}", e);
        }
        return SUCCESS;
    }

    public String searchAlienationByPersonName() {
        logger.debug("search Application By Person Name {} by {}", serchedAlienationHolderName, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            landApplicationList.addAll(landApplicationManagementService.searchAlienationsByPersonName(serchedAlienationHolderName, user, WorkflowTask.CONDITION_SATISFIED));
            populateDistricts();
            populateAlienationMethodNames();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        serchedAlienationHolderName = "";
        return SUCCESS;
    }

    public String searchAlienationByHolderNIC() {
        logger.debug("search Application By Person NIC {} by {}", searchedAlienationHolderNIC, user);
        try {
            landApplicationList = new ArrayList<LandApplication>();
            landApplicationList.addAll(landApplicationManagementService.searchAlienationsByNIC(searchedAlienationHolderNIC, user, WorkflowTask.CONDITION_SATISFIED));
            populateDistricts();
            populateAlienationMethodNames();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchedAlienationHolderNIC = "";
        return SUCCESS;
    }

    public String searchAlienationByAlienationSerialNumber() {
        logger.debug("search Application By Alienation Serial Number {} by {}", searchedAlienationSerialNumber, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            long searchedAlienationSerialNumberLong = 0;
            if (!"".equals(searchedAlienationSerialNumber)) {
                searchedAlienationSerialNumberLong = Long.parseLong(searchedAlienationSerialNumber);

            }
            landApplicationList.addAll(landApplicationManagementService.searchAlienationByAlienationSerialNumber(searchedAlienationSerialNumberLong, user, WorkflowTask.CONDITION_SATISFIED));
            populateDistricts();
            populateAlienationMethodNames();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchedAlienationSerialNumber = "";
        return SUCCESS;
    }

    public String searchAlienationByLandSerialNumber() {
        logger.debug("search Application By Land Serial Number {} by {}", searchedAlienationLandSerialNumber, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            long searchedAlienationLandSerialNumberLong = 0;
            if (!"".equals(searchedAlienationLandSerialNumber)) {
                searchedAlienationLandSerialNumberLong = Long.parseLong(searchedAlienationLandSerialNumber);
            }
            landApplicationList.addAll(landApplicationManagementService.searchAlienationByLandSerialNumber(searchedAlienationLandSerialNumberLong, user, WorkflowTask.CONDITION_SATISFIED));
            populateDistricts();
            populateAlienationMethodNames();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchedAlienationLandSerialNumber = "";
        return SUCCESS;
    }

    public String searchAlienationByAlienationReferenceNumber() {
        logger.debug("search Application By Alienation Number {} by {}", searchedAlienationNumber, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            landApplicationList.addAll(landApplicationManagementService.searchAlienationByAlienationReferenceNumber(searchedAlienationNumber, user, WorkflowTask.CONDITION_SATISFIED));
            populateDistricts();
            populateAlienationMethodNames();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchedAlienationNumber = "";
        return SUCCESS;
    }

    public String searchAlienationByAlienationMethod() {
        logger.debug("search Application By Alienation Method {} by {}", searchedAlienationMethodId, user.getUsername());
        try {
            landApplicationList = new ArrayList<LandApplication>();
            if (searchedAlienationMethodId == 0) {
                landApplicationList = landApplicationManagementService.searchAllAlienationByMethodId(user, WorkflowTask.CONDITION_SATISFIED);
            } else {
                landApplicationList = landApplicationManagementService.searchAlienationByMethodId(searchedAlienationMethodId, user, WorkflowTask.CONDITION_SATISFIED);
            }
            populateDistricts();
            populateAlienationMethodNames();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        searchedAlienationMethodId = 0;
        return SUCCESS;
    }

    public Holder getHolder() {
        return holder;
    }

    public void setHolder(Holder holder) {
        logger.debug("setHolder");
        this.holder = holder;
    }

    public Contacts getContacts() {
        return contacts;
    }

    public void setContacts(Contacts contacts) {
        logger.debug("setContacts");
        this.contacts = contacts;
    }

    public int getAlienationType() {
        return alienationType;
    }

    public void setAlienationType(int alienationType) {
        logger.debug("setAlienationType");
        this.alienationType = alienationType;
    }

    public Map<Integer, String> getDsDivisionsSelectedList() {
        return dsDivisionsSelectedList;
    }

    public void setDsDivisionsSelectedList(Map<Integer, String> dsDivisionsSelectedList) {
        logger.debug("setDsDivisionsSelectedList");
        this.dsDivisionsSelectedList = dsDivisionsSelectedList;
    }

    public List getLandApplicationList() {
        return landApplicationList;
    }

    public void setLandApplicationList(List landApplicationList) {
        logger.debug("setLandApplicationList");
        this.landApplicationList = landApplicationList;
    }

    public long getApplicationId() {
        return applicationId;
    }

    public void setApplicationId(long applicationId) {
        logger.debug("setApplicationId {}", applicationId);
        this.applicationId = applicationId;
    }

    public int[] getDsDivisionsSelected() {
        return dsDivisionsSelected;
    }

    public void setDsDivisionsSelected(int[] dsDivisionsSelected) {
        logger.debug("setDsDivisionsSelected {}", dsDivisionsSelected);
        this.dsDivisionsSelected = dsDivisionsSelected;
    }

    public int getEditMode() {
        return editMode;
    }

    public void setEditMode(int editMode) {
        logger.debug("setEditMode {}", editMode);
        this.editMode = editMode;
    }

    public long getPersonId() {
        return personId;
    }

    public void setPersonId(long personId) {
        logger.debug("setPersonId {}", personId);
        this.personId = personId;
    }

    public long getContactId() {
        return contactId;
    }

    public void setLandApplication(LandApplication landApplication) {
        this.landApplication = landApplication;
    }

    public void setContactId(long contactId) {

        logger.debug("setContactId {}", contactId);
        this.contactId = contactId;
    }

    public long getInitApplicationId() {
        return initApplicationId;
    }

    public void setInitApplicationId(long initApplicationId) {
        logger.debug("initAppId setter is {}", initApplicationId);
        this.initApplicationId = initApplicationId;
    }

    public Map<Integer, String> getDistrictList() {
        return districtList;
    }

    public void setDistrictList(Map<Integer, String> districtList) {
        logger.debug("setDistrictList");
        this.districtList = districtList;
    }

    public Map<Integer, String> getDsDivisionList() {
        return dsDivisionList;
    }

    public void setDsDivisionList(Map<Integer, String> dsDivisionList) {
        logger.debug("setDsDivisionList");
        this.dsDivisionList = dsDivisionList;
    }

    public List<Child> getChildren() {
        return children;
    }

    public void setChildren(List<Child> children) {
        logger.debug("setChildren");
        this.children = children;
    }

    public double getRental() {
        return rental;
    }

    public void setRental(double rental) {
        logger.debug("setRental");
        this.rental = rental;
    }

    public List<Land> getLandList() {
        return landList;
    }

    public void setLandList(List<Land> landList) {
        logger.debug("setLandList");
        this.landList = landList;
    }

    public long getLandId() {
        return landId;
    }

    public void setLandId(long landId) {
        logger.debug("setLandId");
        this.landId = landId;
    }

    public long getLandReferenceNumber() {
        return landReferenceNumber;
    }

    public void setLandReferenceNumber(long landId) {
        logger.debug("setLandReferenceNumber");
        this.landReferenceNumber = landId;
    }

    public Map<Integer, String> getAlienationMethodList() {
        return alienationMethodList;
    }

    public void setAlienationMethodList(Map<Integer, String> alienationMethodList) {
        logger.debug("setAlienationMethodList");
        this.alienationMethodList = alienationMethodList;
    }

    public Map<Integer, String> getGnDivisionList() {
        return gnDivisionList;
    }

    public void setGnDivisionList(Map<Integer, String> gnDivisionList) {
        logger.debug("setGnDivisionList");
        this.gnDivisionList = gnDivisionList;
    }

    public Land getLand() {
        return land;
    }

    public void setLand(Land land) {
        logger.debug("setLand");
        this.land = land;
    }

    public LandAssociation getLandAssociation() {
        return landAssociation;
    }

    public void setLandAssociation(LandAssociation landAssociation) {
        logger.debug("setLandAssociation");
        this.landAssociation = landAssociation;
    }

    public int getAlienationMethod() {
        return alienationMethod;
    }

    public void setAlienationMethod(int alienationMethod) {
        logger.debug("setAlienationMethod");
        this.alienationMethod = alienationMethod;
    }

    public boolean isInitGrantPage() {
        return initGrantPage;
    }

    public void setInitGrantPage(boolean initGrantPage) {
        logger.debug("setAlienationMethod");
        this.initGrantPage = initGrantPage;
    }

    public String getPermitNo() {
        return permitNo;
    }

    public void setPermitNo(String permitNo) {
        this.permitNo = permitNo;
    }

    public Map<Integer, String> getPurposeList() {
        return purposeList;
    }

    public void setPurposeList(Map<Integer, String> purposeList) {
        this.purposeList = purposeList;
    }

    public String getDistrictName() {
        return districtName;
    }

    public void setDistrictName(String districtName) {
        this.districtName = districtName;
    }

    public String getDsDivisionName() {
        return dsDivisionName;
    }

    public void setDsDivisionName(String dsDivisionName) {
        this.dsDivisionName = dsDivisionName;
    }

    public String[] getAlienationMethodSelectedList() {
        return alienationMethodSelectedList;
    }

    public void setAlienationMethodSelectedList(String[] alienationMethodSelectedList) {
        this.alienationMethodSelectedList = alienationMethodSelectedList;
    }

    public Map<Integer, String> getAmSelectedList() {
        return amSelectedList;
    }

    public void setAmSelectedList(Map<Integer, String> amSelectedList) {
        this.amSelectedList = amSelectedList;
    }

    public Map<Integer, String> getAlienationMethodSet() {
        return alienationMethodSet;
    }

    public void setAlienationMethodSet(Map<Integer, String> alienationMethodSet) {
        this.alienationMethodSet = alienationMethodSet;
    }

    public String getAssociationComment() {
        return associationComment;
    }

    public void setAssociationComment(String associationComment) {
        this.associationComment = associationComment;
    }

    public Map<Integer, String> getAlienationTypeList() {
        return alienationTypeList;
    }

    public void setAlienationTypeList(Map<Integer, String> alienationTypeList) {
        this.alienationTypeList = alienationTypeList;
    }

    public Double getHectare() {
        return hectare;
    }

    public void setHectare(Double hectare) {
        this.hectare = hectare;
    }

    public int getGnDivisionName() {
        return gnDivisionId;
    }

    public void setGnDivisionName(int gnDivisionName) {
        this.gnDivisionId = gnDivisionName;
    }

    public String getLocalAuthorityName() {
        return localAuthorityName;
    }

    public void setLocalAuthorityName(String localAuthorityName) {
        this.localAuthorityName = localAuthorityName;
    }

    public String getGeologicalType() {
        return geologicalType;
    }

    public void setGeologicalType(String geologicalType) {
        this.geologicalType = geologicalType;
    }

    public String getAlienationMethodName() {
        return alienationMethodName;
    }

    public void setAlienationMethodName(String alienationMethodName) {
        this.alienationMethodName = alienationMethodName;
    }

    public List<Alienation> getAlienationList() {
        return alienationList;
    }

    public void setAlienationList(List<Alienation> alienationList) {
        this.alienationList = alienationList;
    }

    public long getLandRefNumber() {
        return landRefNumber;
    }

    public void setLandRefNumber(long landRefNumber) {
        this.landRefNumber = landRefNumber;
    }

    public Contacts getContactPerson() {
        return contactPerson;
    }

    public void setContactPerson(Contacts contactPerson) {
        this.contactPerson = contactPerson;
    }

    public long[] getLandSelected() {
        return landSelected;
    }

    public void setLandSelected(long[] landSelected) {
        this.landSelected = landSelected;
    }

    public int getNewAlienation() {
        return newAlienation;
    }

    public void setNewAlienation(int newAlienation) {
        this.newAlienation = newAlienation;
    }

    public String getSearchText() {
        return searchText;
    }

    public void setSearchText(String searchText) {
        this.searchText = searchText;
    }

    public int getDsDivisionId() {
        return dsDivisionId;
    }

    public void setDsDivisionId(int dsDivisionId) {
        this.dsDivisionId = dsDivisionId;
    }

    public void setDistrictId(int districtId) {
        this.districtId = districtId;
    }

    public int getDistrictId() {
        return districtId;
    }

    public boolean isComplete() {
        return isComplete;
    }

    public void setComplete(boolean complete) {
        isComplete = complete;
    }

    public Date getDueDate() {
        return dueDate;
    }

    public void setDueDate(Date dueDate) {
        this.dueDate = dueDate;
    }

    public String getOrdsName() {
        return ordsName;
    }

    public void setOrdsName(String ordsName) {
        this.ordsName = ordsName;
    }

    public int getSignOrNot() {
        return signOrNot;
    }

    public void setSignOrNot(int signOrNot) {
        this.signOrNot = signOrNot;
    }

    public Map<Integer, String> getDistrictListAll() {
        return districtListAll;
    }

    public void setDistrictListAll(Map<Integer, String> districtListAll) {
        this.districtListAll = districtListAll;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public List<Land> getLandChildList() {
        return landChildList;
    }

    public void setLandChildList(List<Land> landChildList) {
        this.landChildList = landChildList;
    }

    public List<CommunicationMethod> getCommunicationMethodAsList() {
        return Arrays.asList(CommunicationMethod.values());
    }

    public void setCommunicationMethodAsList(List<CommunicationMethod> communicationMethodAsList) {
        this.communicationMethodAsList = communicationMethodAsList;
    }

    public String getObjections() {
        return objections;
    }

    public void setObjections(String objections) {
        this.objections = objections;
    }

    public int getSearchValue() {
        return searchValue;
    }

    public void setSearchValue(int searchValue) {
        this.searchValue = searchValue;
    }

    public int getOtherMode() {
        return otherMode;
    }

    public void setOtherMode(int otherMode) {
        this.otherMode = otherMode;
    }

    public String getSlcObjections() {
        return slcObjections;
    }

    public void setSlcObjections(String slcObjections) {
        this.slcObjections = slcObjections;
    }

    public int getOnlineApplicantDistrictId() {
        return onlineApplicantDistrictId;
    }

    public void setOnlineApplicantDistrictId(int onlineApplicantDistrictId) {
        this.onlineApplicantDistrictId = onlineApplicantDistrictId;
    }

    public int getOnlineApplicantDsDivisionId() {
        return onlineApplicantDsDivisionId;
    }

    public void setOnlineApplicantDsDivisionId(int onlineApplicantDsDivisionId) {
        this.onlineApplicantDsDivisionId = onlineApplicantDsDivisionId;
    }

    public String getSerchedAlienationHolderName() {
        return serchedAlienationHolderName;
    }

    public void setSerchedAlienationHolderName(String serchedAlienationHolderName) {
        this.serchedAlienationHolderName = serchedAlienationHolderName;
    }

    public String getSearchedAlienationHolderNIC() {
        return searchedAlienationHolderNIC;
    }

    public void setSearchedAlienationHolderNIC(String searchedAlienationHolderNIC) {
        this.searchedAlienationHolderNIC = searchedAlienationHolderNIC;
    }

    public String getSearchedAlienationSerialNumber() {
        return searchedAlienationSerialNumber;
    }

    public void setSearchedAlienationSerialNumber(String searchedAlienationSerialNumber) {
        this.searchedAlienationSerialNumber = searchedAlienationSerialNumber;
    }

    public String getSearchedAlienationLandSerialNumber() {
        return searchedAlienationLandSerialNumber;
    }

    public void setSearchedAlienationLandSerialNumber(String searchedAlienationLandSerialNumber) {
        this.searchedAlienationLandSerialNumber = searchedAlienationLandSerialNumber;
    }

    public String getSearchedAlienationNumber() {
        return searchedAlienationNumber;
    }

    public void setSearchedAlienationNumber(String searchedAlienationNumber) {
        this.searchedAlienationNumber = searchedAlienationNumber;
    }

    public int getSearchedAlienationMethodId() {
        return searchedAlienationMethodId;
    }

    public void setSearchedAlienationMethodId(int searchedAlienationMethodId) {
        this.searchedAlienationMethodId = searchedAlienationMethodId;
    }

    public boolean getObjectionDisabled() {
        return objectionDisabled;
    }

    public void setObjectionDisabled(boolean status) {
        this.objectionDisabled = status;
    }

    public boolean isIgnoreWarnings() {
        return ignoreWarnings;
    }

    public void setIgnoreWarnings(boolean ignoreWarnings) {
        this.ignoreWarnings = ignoreWarnings;
    }
}
